#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
默认构建工具
扩展SCons环境，添加构建系统功能
"""

import os
import sys
import time
import logging
from pathlib import Path
from SCons.Script import *
from module_scanner import ModuleScanner
from build_manager import BuildManager
from target_registry import TargetRegistry, TargetType, BuildTarget
from module_helpers import ModuleHelper
# 配置logging
logging.basicConfig(level=logging.INFO, format='%(message)s')

def generate(env):
    """
    生成构建工具
    """
    # 添加构建工具路径
    build_tools_root = env['BUILD_TOOLS_ROOT']
    sys.path.insert(0, build_tools_root)

    # 使用Tool方式加载各个工具，指定工具路径
    env.Tool('option', toolpath=[build_tools_root])
    env.Tool('feature_load', toolpath=[build_tools_root])
    env.Tool('project_inc_load', toolpath=[build_tools_root])
    env.Tool('project_env_load', toolpath=[build_tools_root])
    env.Tool('binary', toolpath=[build_tools_root])
    env.Tool('proto_support', toolpath=[build_tools_root])

    # 加载PROJECT_BUILD_CONFIG配置脚本（如果设置了环境变量）
    project_build_config = os.environ.get('PROJECT_BUILD_CONFIG')
    if project_build_config:
        if os.path.isfile(project_build_config):
            # 获取配置脚本的目录和文件名
            config_dir = os.path.dirname(os.path.abspath(project_build_config))
            config_name = os.path.splitext(os.path.basename(project_build_config))[0]

            logging.info(f"Loading PROJECT_BUILD_CONFIG: {project_build_config}")
            try:
                env.Tool(config_name, toolpath=[config_dir])
                logging.info(f"Successfully loaded build config: {config_name}")
            except Exception as e:
                logging.warning(f"Failed to load PROJECT_BUILD_CONFIG '{project_build_config}': {e}")
        else:
            logging.warning(f"PROJECT_BUILD_CONFIG file not found: {project_build_config}")

    # 创建全局构建管理器和目标注册表
    env._build_manager = BuildManager(env)
    env._target_registry = TargetRegistry()
    env._build_manager.set_target_registry(env._target_registry)
    env._module_scanner = ModuleScanner()

    # 创建ModuleHelper实例
    env._module_helper = ModuleHelper(env, env._build_manager, env._target_registry, '.')

    # 初始化构建时间跟踪
    env._build_start_time = time.time()
    env._build_success = True  # 添加构建状态跟踪

    def get_build_time(env):
        """获取构建时间"""
        build_time_seconds = time.time() - env._build_start_time

        # 转换为分.秒.毫秒格式
        total_milliseconds = int(build_time_seconds * 1000)

        minutes = total_milliseconds // (60 * 1000)
        remaining_ms = total_milliseconds % (60 * 1000)
        seconds = remaining_ms // 1000
        milliseconds = remaining_ms % 1000

        if minutes > 0:
            return f"{minutes}min {seconds}sec {milliseconds}ms"
        elif seconds > 0:
            return f"{seconds}sec {milliseconds}ms"
        else:
            return f"{milliseconds}ms"





    def scan_and_load_modules(env, root_dir):
        """
        扫描并加载所有Module文件

        Args:
            root_dir: 根目录
        """
        module_files = env._module_scanner.scan_modules(root_dir)

        logging.info("")
        logging.info("╔═════════════════════════════════════════════════════════════════════════╗")
        logging.info("║                        Phase2 -- Load module files                     ║")
        logging.info("╚═════════════════════════════════════════════════════════════════════════╝")
        logging.info(f"Found {len(module_files)} module files:")
        for module_file in module_files:
            logging.info(f"  ✓ {module_file}")

        # 加载所有Module
        for module_file in module_files:
            try:
                # 设置当前Module目录
                module_dir = os.path.dirname(module_file)
                module_env = env.Clone()
                module_env['MODULE_DIR'] = module_dir

                # 确保module_env有必要的属性
                module_env._module_helper = env._module_helper
                module_env._build_manager = env._build_manager
                module_env._target_registry = env._target_registry
                module_env._module_scanner = env._module_scanner

                # 执行Module文件
                def mock_import(var_name):
                    if var_name == 'env':
                        return module_env
                    else:
                        raise NameError(f"Import of non-existent variable '{var_name}'")

                module_globals = {
                    'Import': mock_import,
                    'env': module_env,
                    'Dir': Dir,
                    'File': File,
                    'Glob': Glob,
                    'logging': logging
                }

                with open(module_file, 'r', encoding='utf-8') as f:
                    module_code = f.read()

                exec(module_code, module_globals)

            except Exception as e:
                logging.error(f"[ERROR] Failed to load module {module_file}: {e}")
                Exit(1)

        # 所有模块加载完成后，进行自动依赖推导
        logging.info("")
        logging.info("╔═════════════════════════════════════════════════════════════════════════╗")
        logging.info("║                      Phase3 -- Dependency analysis                      ║")
        logging.info("╚═════════════════════════════════════════════════════════════════════════╝")
        _auto_resolve_dependencies(env)

    def _auto_resolve_dependencies(env):
        """
        自动推导依赖关系

        Args:
            env: SCons环境
        """
        dependencies_found = []
        all_dependencies = {}  # 收集所有依赖关系用于显示

        # 遍历所有目标，检查其static_libs、shared_libs和libs中是否有内部目标
        for target_name in env._target_registry.get_all_targets():
            target = env._target_registry.get_target(target_name)
            if target:
                # 检查所有类型的库依赖
                all_libs = []
                all_libs.extend(target.static_libs)
                all_libs.extend(target.shared_libs)


                for lib_name in all_libs:
                    # 如果库名对应一个内部目标，自动添加依赖
                    if env._target_registry.has_target(lib_name):
                        if lib_name not in target.dependencies:
                            target.add_dependency(lib_name)
                            dependencies_found.append(f"{target_name} -> {lib_name}")

                # 收集所有依赖关系用于显示（包括已存在的依赖）
                if target.dependencies:
                    if target_name not in all_dependencies:
                        all_dependencies[target_name] = []
                    for dep_name in target.dependencies:
                        dep_target = env._target_registry.get_target(dep_name)
                        if dep_target:
                            all_dependencies[target_name].append(dep_name)

        # 显示自动推导的依赖
        if dependencies_found:
            logging.info("Auto-resolved dependencies:")
            # 将依赖关系按目标分组，合并显示
            target_deps = {}
            for dep in dependencies_found:
                target, lib = dep.split(" -> ")
                if target not in target_deps:
                    target_deps[target] = []
                target_deps[target].append(lib)

            # 按目标打印依赖关系，多个依赖在一行显示
            for target, libs in target_deps.items():
                if len(libs) == 1:
                    logging.info(f"  - {target} -> {libs[0]}")
                else:
                    logging.info(f"  - {target} -> {', '.join(libs)}")
        else:
            logging.info("No dependencies to resolve.")

        # 显示所有依赖关系（包括头文件库等）
        if all_dependencies:
            logging.info("All target dependencies:")
            for target, deps in all_dependencies.items():
                if len(deps) == 1:
                    logging.info(f"  - {target} -> {deps[0]}")
                else:
                    logging.info(f"  - {target} -> {', '.join(deps)}")

    def build_target(env, target_name):
        """
        构建指定目标

        Args:
            target_name: 目标名称
        """
        if env._target_registry.has_target(target_name):
            built_nodes = env._build_manager.build_target(target_name)
            # 设置为默认目标，让SCons知道要构建什么
            if built_nodes:
                # 展平节点列表
                flat_nodes = []
                for node in built_nodes:
                    if isinstance(node, list):
                        flat_nodes.extend(node)
                    else:
                        flat_nodes.append(node)
                # 创建别名并设置为默认目标
                alias = env.Alias(target_name, flat_nodes)
                env.Default(alias)
        else:
            env._build_success = False
            logging.error(f"Error: Target '{target_name}' not found")
            logging.info("Available targets:")
            for target in env._target_registry.get_all_targets():
                logging.info(f"  - {target}")
            # 不直接Exit，让程序继续到Phase5显示结果
            return False
        return True

    def build_all_targets(env):
        """
        构建所有目标
        """
        all_targets = env._target_registry.get_all_targets()
        env._build_manager.build_all_targets()

    def glob_sources(env, pattern):
        """
        使用glob模式匹配源文件

        Args:
            pattern: glob模式

        Returns:
            匹配的文件列表
        """
        import glob

        module_dir = env.get('MODULE_DIR', '.')
        if os.path.isabs(pattern):
            search_pattern = pattern
        else:
            search_pattern = os.path.join(module_dir, pattern)

        return glob.glob(search_pattern)

    # 将方法添加到环境中
    env.AddMethod(scan_and_load_modules, 'ScanAndLoadModules')
    env.AddMethod(build_target, 'BuildTarget')
    env.AddMethod(build_all_targets, 'BuildAllTargets')
    env.AddMethod(glob_sources, 'GlobSources')
    env.AddMethod(get_build_time, 'get_build_time')





def exists(env):
    """
    检查工具是否存在
    """
    return True